module sys_array_n_n #(
    parameter DW = 8,
    parameter ROW = 8,
    parameter PE_NUM = 64
)(
     input wire clk,
    input wire rst,
    input wire data_rst,
    input wire ini,
    input wire data_en,
    input wire [DW*ROW-1:0] act,    //总线的形态输入
    input wire [DW*ROW-1:0] wei,
    input wire [DW*2*ROW-1:0] sum,
    output wire [DW*ROW-1:0] n_act,    //总线的形态输入
    output wire [DW*ROW-1:0] n_wei,
    output wire [DW*2*ROW-1:0] n_sum
);

wire [DW-1:0]       activation_in   [0:PE_NUM-1];
wire [DW-1:0]       weight_in       [0:PE_NUM-1];
wire [DW*2-1:0]     pre_sum_in          [0:PE_NUM-1];

wire [DW-1:0]   	next_weight     [0:PE_NUM-1];
wire [DW-1:0]   	next_activation [0:PE_NUM-1];
wire [DW*2-1:0] 	next_sum        [0:PE_NUM-1];

//和端口的连接
genvar i;
generate for(i=0;i<ROW;i=i+1) begin : PAD0
    assign activation_in[i] = act[(i+1)*DW-1:i*DW];     //输入
    assign weight_in[i] = wei[(i+1)*DW-1:i*DW];         //输入
end
endgenerate

generate for(i=0;i<ROW;i=i+1) begin : PAD1
    assign n_act[(i+1)*DW-1:i*DW] = next_activation[i+PE_NUM-ROW];
    assign n_wei[(i+1)*DW-1:i*DW] = next_weight[i+PE_NUM-ROW];
end
endgenerate

generate for(i=0;i<ROW;i=i+1) begin : PAD2
    assign pre_sum_in[i*ROW] = sum[(i+1)*DW-1:i*DW];    //输入
end
endgenerate

generate for(i=0;i<ROW;i=i+1) begin : PAD3
    assign n_sum[(i+1)*DW-1:i*DW] = next_sum[(i+1)*ROW-1];
end
endgenerate

//8*8 pe  = 64 pe

generate for(i=0;i<PE_NUM;i=i+1) begin : U
    PE #(
        .DW 		( DW 		))
    u_PE(
        //ports
        .clk             		( clk             		),
        .rst             		( rst             		),
        .data_rst        		( data_rst        		),
        .ini             		( ini             		),
        .data_en         		( data_en         		),
        .activation_in   		( activation_in[i]   		),
        .weight_in       		( weight_in[i]       		),
        .pre_sum_in      		( pre_sum_in[i]      		),
        .next_weight     		( next_weight[i]     		),
        .next_activation 		( next_activation[i] 		),
        .next_sum        		( next_sum[i]        		)
    );
end
endgenerate

/*每个小PE模块之间的连接
 | | | | | | | | 
-0-1-2-3-4-5-6-7-
 | | | | | | | | 
-8-9-10  ...
- ...
-       -61-62-63-
 | | | | | | | | 
*/

generate for(i=ROW;i<PE_NUM;i=i+1) begin : connect1
    assign activation_in[i] = next_activation[i-ROW];
    assign weight_in[i] = next_weight[i-ROW];
end
endgenerate

generate for(i=0;i<PE_NUM;i=i+1) begin : connect2
    if (i%ROW != 0) begin
        assign pre_sum_in[i] = next_sum[i-1];
    end
end
endgenerate

endmodule